home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DJGPP
/
CBGRX103.ZIP
/
contrib
/
libgrx
/
ndrivers
/
vesadrv.c
< prev
next >
Wrap
Text File
|
1993-12-06
|
8KB
|
229 lines
/**
** VESADRV.C ---- EGA, VGA, VESA Super VGA driver for GRX 1.03
**
** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
** Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
** Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl
**
** This file is distributed under the terms listed in the document
** "copying.dj", available from DJ Delorie at the address above.
** A copy of "copying.dj" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.dj".
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**/
#pragma inline
#include <dos.h>
#include "vdr.h"
char driver_name[] = { "GRX 1.03 VESA driver" };
#define MAX_TEXT_MODES 20 /* maximum text mode table size */
#define EGA_TEXT_START 6 /* start of the EGA mode table */
#define EGA_TEXT_MODES 5 /* number of EGA text modes (incl end marker) */
GrModeEntry text_mode_table[MAX_TEXT_MODES] = {
{ 80, 25, 2, 0x007, SETUP_STANDARD },
{ 40, 25, 16, 0x001, SETUP_STANDARD },
{ 80, 25, 16, 0x003, SETUP_STANDARD },
{ 80, 28, 16, 0x003, SETUP_8X14_FNT },
{ 80, 50, 16, 0x003, SETUP_8X8_FNT },
{ 0, 0, 0, UNSUP, 0 },
{ 80, 25, 2, 0x007, SETUP_STANDARD }, /* EGA table */
{ 40, 25, 16, 0x001, SETUP_STANDARD },
{ 80, 25, 16, 0x003, SETUP_STANDARD },
{ 80, 43, 16, 0x003, SETUP_8X8_FNT },
{ 0, 0, 0, UNSUP, 0 }
};
#define MAX_GRAPH_MODES 40 /* maximum graphics mode table size */
#define EGA_GRAPH_START 8 /* start of the EGA mode table */
#define EGA_GRAPH_MODES 4 /* number of EGA graphics modes (incl end marker) */
GrModeEntry graphics_mode_table[MAX_GRAPH_MODES] = {
{ 320, 200, 16, 0x00d, SETUP_STANDARD },
{ 640, 200, 16, 0x00e, SETUP_STANDARD },
{ 640, 350, 16, 0x010, SETUP_STANDARD },
{ 640, 480, 16, 0x012, SETUP_STANDARD },
{ 320, 200, 256, 0x013, SETUP_STANDARD },
{ 320, 240, 256, 0x013, SETUP_MODE_X },
{ 360, 480, 256, 0x013, SETUP_MODE_X },
{ 0, 0, 0, UNSUP, 0 },
{ 320, 200, 16, 0x00d, SETUP_STANDARD }, /* EGA table */
{ 640, 200, 16, 0x00e, SETUP_STANDARD },
{ 640, 350, 16, 0x010, SETUP_STANDARD },
{ 0, 0, 0, UNSUP, 0 }
};
#include "pieces/chkevga.c"
#include "pieces/chkvga.c"
#include "pieces/vesainfo.c"
#include "pieces/addmode.c"
#include "paging/vesa.c"
int get_mem_size(int scan_line_len,int rows)
{
_AX = scan_line_len;
_DX = rows;
asm mul dx;
asm add ax,4095;
asm adc dx,0;
asm mov cx,12;
asm shr ax,cl;
asm mov cx,4;
asm shl dx,cl;
asm add ax,dx;
return(_AX); /* in 4 kByte units !! */
}
int do_driver_init(void)
{
VgaInfoBlock *vb;
ModeInfoBlock *mb;
short far *modeptr;
int mode,colors;
if(!check_for_EGAVGA()) return(0);
if(!check_for_VGA()) {
HDR->driver_flags = GRD_EGA | GRD_NEW_DRIVER | GRD_NO_RW | GRD_128K;
HDR->memory_size = (128 / 4);
tblcopy(text_mode_table,&text_mode_table[EGA_TEXT_START],EGA_TEXT_MODES);
tblcopy(graphics_mode_table,&graphics_mode_table[EGA_GRAPH_START],EGA_GRAPH_MODES);
return(1);
}
HDR->memory_size = (256 / 4);
if((vb = VESAgetInfo()) != 0) {
modeptr = vb->VideoModePtr;
while((mode = *modeptr++) != (-1)) {
if((mb = VESAgetModeInfo(mode)) == 0) continue;
if((mb->ModeAttributes & MODE_EXTINFO) == 0) {
/* I am really delighted to have this mode, but.. */
/* what can I do with it without resolution info? */
continue;
}
if(mb->ModeAttributes & MODE_ISGRAPHICS) {
if(mb->BitsPerPixel < 16)
colors = 1 << mb->BitsPerPixel;
else if(mb->BitsPerPixel > 16)
colors = 0xc000U | mb->BitsPerPixel;
else if(VESAversion >= VESA_VERSION(1,2))
colors = mb->ReservedMaskSize ? 32768U : (0xc000 + 16);
else if(HDR->driver_options & GRD_15_PLANE_MODE)
colors = 32768U;
else colors = 0xc000 + 16;
add_graphics_mode(mb->XResolution,mb->YResolution,
colors,mode,SETUP_STANDARD
);
mode = get_mem_size(mb->BytesPerScanLine,mb->YResolution);
if(mb->MemoryModel == MODEL_4PLANE) mode <<= 2;
mode = (mode + (512/4 - 1)) & ~(512/4 - 1); /* round up to next 0.5 MB */
if(HDR->memory_size < mode) HDR->memory_size = mode;
}
else {
add_text_mode(mb->XResolution,mb->YResolution,16,mode,SETUP_STANDARD);
if(mb->YResolution == 25) {
add_text_mode(mb->XResolution,28,16,mode,SETUP_8X14_FNT);
add_text_mode(mb->XResolution,50,16,mode,SETUP_8X8_FNT);
}
}
}
}
mode = GRD_256K;
if(HDR->memory_size >= (512 / 4)) mode = GRD_512K;
if(HDR->memory_size >= (1024 / 4)) mode = GRD_1024K;
if(HDR->memory_size >= (1536 / 4)) mode = GRD_1536K;
if(HDR->memory_size >= (2048 / 4)) mode = GRD_2048K;
if(HDR->memory_size >= (3072 / 4)) mode = GRD_3072K;
if(HDR->memory_size >= (4096 / 4)) mode = GRD_4096K;
HDR->driver_flags = GRD_VGA | GRD_NEW_DRIVER | GRD_NO_RW | mode;
return(1);
}
#include "pieces/textfont.c"
#include "pieces/mode_x.c"
int do_mode_set(GrModeEntry *md,int noclear,int *vw,int *vh,char *vflag)
{
int BIOSno,memmode,pgmode;
switch(md->mode.vdr.custom_setup_index) {
case SETUP_8X14_FNT: return(mode_set_8x14_font(md,noclear));
case SETUP_8X8_FNT: return(mode_set_8x8_font(md,noclear));
case SETUP_MODE_X: return(mode_set_256_planar(md,noclear));
}
if((BIOSno = md->mode.vdr.BIOS_mode) > 0x13) {
if(noclear) BIOSno |= 0x8000;
_AX = VESA_FUNC + VESA_SET_MODE;
_BX = BIOSno;
geninterrupt(0x10);
if(_AX != VESA_SUCCESS) return(-1);
}
else {
if(noclear) BIOSno |= 0x80;
_AX = BIOSno;
geninterrupt(0x10);
}
pgmode = setup_VESA_paging(md);
if(pgmode == (-1)) return(-1);
switch((unsigned)md->number_of_colors) {
case 2U: memmode = GRD_1_PLANE; break;
case 16U: memmode = GRD_4_PLANES; break;
case 256U: memmode = (HDR->driver_options & GRD_FAST_256_MODE) ? GRD_8_F_PLANES : GRD_8_PLANES; break;
case 32768U: memmode = GRD_16_PLANES; break;
case 0xc000U+16: memmode = GRD_16_R_PLANES; break;
case 0xc000U+24: memmode = GRD_24_PLANES; break;
default: return(-1);
}
if((md->number_of_colors > 256) && (VESAversion >= VESA_VERSION(1,2))) {
ModeInfoBlock *mb = VESAgetModeInfo(md->mode.vdr.BIOS_mode);
if(mb) {
HDR->r_mask = mb->RedMaskSize;
HDR->r_offs = mb->RedMaskPos;
HDR->g_mask = mb->GreenMaskSize;
HDR->g_offs = mb->GreenMaskPos;
HDR->b_mask = mb->BlueMaskSize;
HDR->b_offs = mb->BlueMaskPos;
HDR->f_mask = mb->ReservedMaskSize;
HDR->f_offs = mb->ReservedMaskPos;
/* is that 16 really only 15 ? */
if((memmode == GRD_16_R_PLANES) && (HDR->f_mask > 0)) memmode = GRD_16_PLANES;
}
}
if((*vw > md->width) || (*vh > md->height)) {
int virw = *vw;
int virh = *vh;
_BX = (virw > md->width) ? 0 : 1; /* inquire only if width stays the same */
_CX = virw;
_AX = VESA_FUNC + VESA_SCAN_LNLEN;
geninterrupt(0x10);
if(_AX == VESA_SUCCESS) {
virw = _CX;
virh = _DX;
HDR->line_offset = _BX;
if((virw > md->width) || (virh > md->height)) {
*vw = virw;
*vh = virh;
*vflag = 1;
}
}
}
return((HDR->driver_flags & ~(GRD_PLANE_MASK | GRD_PAGING_MASK)) | memmode | pgmode);
}
void do_screen_start_set(int *cp,int *rp)
{
_CX = *cp;
_DX = *rp;
_BX = 0;
_AX = VESA_FUNC + VESA_DISP_START;
geninterrupt(0x10);
if(_AX == VESA_SUCCESS) {
*cp = _CX;
*rp = _DX;
}
}
#include "pieces/vdrmain.c"